package model.session;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import model.cnf.CNF;

/**
 * <p>
 * A {@link SessionBlock} that represent a cnf.
 * </p>
 * <p>
 * You can access to all the operation that have been lunch using this cnf.
 * </p>
 * <p>
 * This class can be use a first block see {@link SessionBlock}.
 * </p>
 * 
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 *         igsat 2010
 * 
 */
public class CNFUse extends SessionBlock {

	private CNF										cnf;

	private Map<PreprocessorExecutionBlock, CNFUse>	preproc	= new HashMap<PreprocessorExecutionBlock, CNFUse>();

	private Set<SolverExecutionBlock>				solver	= new HashSet<SolverExecutionBlock>();

	/**
	 * Create a cnfuse.
	 * 
	 * @param first
	 *            the first block see {@link SessionBlock}
	 * @param cnf
	 *            the cnf corresponding to the usecnf
	 */
	public CNFUse(SessionBlock first, CNF cnf) {
		super(first);

		if (cnf == null)
			throw new IllegalArgumentException();
		this.cnf = cnf;

		// TODO Auto-generated constructor stub
	}

	/**
	 * create a cnfuse use as a first block.
	 * 
	 * @param cnf
	 *            the cnf corresponding to the usecnf
	 */
	public CNFUse(CNF cnf) {
		super();

		if (cnf == null)
			throw new IllegalArgumentException();
		this.cnf = cnf;
		// TODO Auto-generated constructor stub
	}

	/**
	 * @return the cnf that correspond to the CNFUSe.
	 */
	public CNF getCnf() {
		return cnf;
	}

	/**
	 * @param cnf
	 *            the cnf to set
	 */
	public void setCnf(CNF cnf) {
		this.cnf = cnf;
	}

	/**
	 * @return the preprocessor that was executed on that CNF associate with the CNF that result
	 *         from this execution.
	 */
	public Map<PreprocessorExecutionBlock, CNFUse> getPreproc() {
		return preproc;
	}

	/**
	 * @return the solver that was executed on this CNF.
	 */
	public Set<SolverExecutionBlock> getSolver() {
		return solver;
	}

	/**
	 * Add the proprecessor to the list of preprocessor that was executed on that CNF.
	 * 
	 * @param preproc
	 *            the preprocesso to add.
	 * @param cnf
	 *            the CNF result.
	 */
	public void addPreproc(PreprocessorExecutionBlock preproc, CNFUse cnf) {
		this.preproc.put(preproc, cnf);
	}

	/**
	 * Add the solver to the list of solver that has been executed on that cnf.
	 * 
	 * @param solver
	 *            the solver to add.
	 */
	public void addSolver(SolverExecutionBlock solver) {
		this.solver.add(solver);
	}

	/**
	 * Remove the preprocessor to the list of preprocessor that has been executed on that cnf.
	 * 
	 * @param preproc
	 *            the preprocessor.
	 * @return the CNF that result from the execution of the preprocessor.
	 */
	public CNFUse removePreproc(PreprocessorExecutionBlock preproc) {
		CNFUse res = this.preproc.remove(preproc);
		if (res == null)
			throw new IllegalArgumentException();
		return res;
	}

	/**
	 * Remove the solver to the list of solver that has been executed on that cnf.
	 * 
	 * @param solver
	 *            the solver
	 */
	public void removeSolver(SolverExecutionBlock solver) {
		if (!this.solver.remove(solver))
			throw new IllegalArgumentException();
	}

}
